package pers.w.chaptertalk.reader;

import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.TranslateAnimation;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import pers.w.chaptertalk.LaunchActivity;
import pers.w.chaptertalk.MyService;
import pers.w.chaptertalk.R;
import pers.w.chaptertalk.funs.BookInfo;
import pers.w.chaptertalk.funs.ChapterInfo;
import pers.w.chaptertalk.funs.ChapterThread;
import pers.w.chaptertalk.funs.ContentThread;
import pers.w.chaptertalk.funs.Fun;
import pers.w.chaptertalk.funs.IReader;
import pers.w.chaptertalk.funs.db.Tab_Book;
import pers.w.chaptertalk.funs.db.Tab_BookProgress;
import pers.w.chaptertalk.funs.db.Tab_Chapter;

public class ReaderActivity extends AppCompatActivity implements IReader {

    private static final String TAG = "ReaderActivity";
    BookInfo book;
    List<Map<String, String>> chapters;
    ChapterInfo chapter;
    RelativeLayout rl_reader_and_prepare;
    private TextView tv_msg;

    SideBar sidebar;
    StatusBar statusBar;
    ControlWindow controlWindow;
    SettingWindow settingWindow;
    Spoken_Setting spoken_setting;
    Talks talks;
    TextView tv_title;
    TextView tv_reader, tv_prepare;

    ReaderControl control;
    int currentChapterIndex;

    ProgressBar pb_loading;
    Animation ltoC;
    Animation ctoL;

    MyService service;
    ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ReaderActivity.this.service = ((MyService.MyIBinder) service).getService();
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }
    };

    void showMsg(String msg) {
        tv_msg.setText(msg);
        tv_msg.setVisibility(View.VISIBLE);
    }

    void hideMsg() {
        tv_msg.setVisibility(View.INVISIBLE);
    }

    void showToask(String msg) {
        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 隐藏标题栏
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        bindService(new Intent(this, MyService.class), conn, Context.BIND_AUTO_CREATE);
        // 隐藏状态栏
        // 定义全屏参数
        int flag = WindowManager.LayoutParams.FLAG_FULLSCREEN;
        getWindow().setFlags(flag, flag);
        setContentView(R.layout.activity_reader);
        assert getSupportActionBar() != null;
        getSupportActionBar().hide();

        ltoC = AnimationUtils.loadAnimation(this, R.anim.left_center);
        ctoL = AnimationUtils.loadAnimation(this, R.anim.center_left);

        tv_title = findViewById(R.id.tv_cur_book_name);
        pb_loading = findViewById(R.id.pb_loading_chapter);
        pb_loading.setVisibility(View.GONE);
        tv_msg = findViewById(R.id.tv_msg);
        initControl();//里面设置了2个tv，再给control，此方法要在使用control前调用

        //先要获取数据，不然后面控件init会空指针
        bindDate();//从数据库获得数据并设置到内部数据
        sidebar = new SideBar(this);
        sidebar.initSidebar();//先赋值sidebar，后面setting要用到
        statusBar = new StatusBar(this);

        controlWindow = new ControlWindow(this);
        controlWindow.setVisibility(false);

        settingWindow = new SettingWindow(this);
        tv_title.setText(String.format("%s > %s", book.getFieldValue(R.string.info_name), chapter == null ? "" : chapter.getName()));

        spoken_setting = new Spoken_Setting(this);
        talks = new Talks(this);
        // setScreenFitler();
        statusBar.runUpdateTimeThread();
    }

    private boolean firsFocus = true;

    @Override//获得焦点的时候，控件加载完成，可以进行实际操作
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        // Log.d(TAG, "onWindowFocusChanged: "+hasFocus);
        //  updateView = hasFocus;
        if (hasFocus) {
            if (lockScreenTime != -1) {
                lockScreenCountdown = lockScreenTime;
                setScreenOn(true);
            }
            if (null != chapter) {
                if (firsFocus)
                    getContent(ReaderControl.NO_CHANGE);
                if (control.getPagesSize()>0)//没有活得分割数据
                    control.updateTV_Reader();
            }
        }

        firsFocus = false;
    }

    @Override
    protected void onDestroy() {

        if (Fun.isDebug()) Log.d(TAG, "onDestroy: ");
        spoken_setting.stopSpoken(true);
        unbindService(conn);
        if (null != chaptersThread) {
            chaptersThread.cancel();
            chaptersThread = null;
        }
        statusBar.cancel();
        if (book != null) {
            control.update_SQL(book.getID());
        }
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (spoken_setting.isPlaying()) return;
        if (talks.isVisibility()) {
            talks.hide();
        } else if (sidebar.isVisibility()) {
            sidebar.setVisibility(false);
        } else if (settingWindow.isVisibility()) {
            settingWindow.setVisibility(false);
        } else if (controlWindow.isVisibility()) {
            controlWindow.setVisibility(false);
        } else {
            finish();
            super.onBackPressed();
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (!spoken_setting.isPlaying()) {
            if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
                page_turning(true);
                return true;
            } else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
                page_turning(false);
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    void setScreenOn(boolean screenOn) {
        if (screenOn) {
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        } else {
            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    }

//    private boolean updateView=true;
//    boolean isUpdateView(){
//        return  updateView;
//    }
//    void setScreenFitler(){
//        final IntentFilter filter= new IntentFilter();
//        filter.addAction(Intent.ACTION_SCREEN_OFF);
//        filter.addAction(Intent.ACTION_SCREEN_ON);
//        registerReceiver(new BroadcastReceiver() {
//            @Override
//            public void onReceive(Context context, Intent intent) {
//                final String action =intent.getAction();
//                if (Intent.ACTION_SCREEN_ON.equals(action)){
//                    updateView = true;
//                }else if (Intent.ACTION_SCREEN_OFF.equals(action)){
//                    updateView=false;
//                }
//            }
//        },filter);
//    }

    private int lockScreenTime = -1, lockScreenCountdown;//秒,lockScreenTime初始-1，就是锁屏时间跟随系统

    void setScreenOn(int lockScreenTime) {
        this.lockScreenTime = lockScreenTime;
        if (lockScreenTime == -1) {
            setScreenOn(false);
        } else {
            setScreenOn(true);
            lockScreenCountdown = lockScreenTime;
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    private void initControl() {
        this.rl_reader_and_prepare = findViewById(R.id.rl_reader_and_prepare);
        //rl_reader_and_prepare.setOrientation(LinearLayout.HORIZONTAL);
        tv_reader = findViewById(R.id.tv_reader);
        tv_prepare = findViewById(R.id.tv_prepare);
        tv_reader.setMovementMethod(LinkMovementMethod.getInstance());
        tv_prepare.setMovementMethod(LinkMovementMethod.getInstance());

        control = new ReaderControl(this, tv_prepare, tv_reader);

        tv_reader.setOnTouchListener(new ReaderOnTouchListener());
        tv_reader.setOnClickListener(v -> {
            // if (spoken_setting.isVisibility() || talks.isVisibility()) return;
            if (spoken_setting.isPlaying()) {
                control.resetClickSpan();
                spoken_setting.setVisibility(!spoken_setting.isVisibility());
                return;
            }

            if (settingWindow.isVisibility()) {
                settingWindow.setVisibility(false);
                control.resetClickSpan();
                return;
            }
            if (controlWindow.isVisibility()) {
                controlWindow.setVisibility(false);
                control.resetClickSpan();
                return;
            }
            if (control.isClickSpan())
                control.resetClickSpan();
            else {
                if (talks.isVisibility()) {
                    talks.hide();
                    return;
                }
                if (v.getTag() != null) {
                    final float w = tv_reader.getWidth();
                    final float h = tv_reader.getHeight();
                    MotionEvent event = (MotionEvent) v.getTag();
                    float x = event.getX();
                    float y = event.getY();
                    if (x < w / 3) {
                        page_turning(false);
                    } else if (x > w * 2 / 3) {
                        page_turning(true);
                    } else {
                        if (y > h / 3 && y < h * 2 / 3) {
                            controlWindow.setVisibility(true);
                        }
                        // newIndex = currentChapterIndex;
                    }
                    v.setTag(null);
                }
            }
        });
    }

    void loading_chapter(int index, int startOrEndOrNoChange) {
        spoken_setting.setCurPageSpokenProgress();//解决停止听书后 上下章节开始听书进度出错

        Log.d(TAG, "loading_chapter: " + index);
        if (index != CHAPTER_NO_CHANGE)
            currentChapterIndex = index;
        synchronized (this) {
            chapter = new ChapterInfo(book.getBookDir(), chapters.get(currentChapterIndex));
        }
        pb_loading.setVisibility(View.VISIBLE);

        tv_reader.setText("加载中");
        tv_title.setText(String.format("%s > %s", book.getFieldValue(R.string.info_name), chapter.getName()));
        getContent(startOrEndOrNoChange);

    }

    private int findChapter(long chapterID) {
        String idStr;
        for (int i = 0; i < chapters.size(); i++) {
            idStr = chapters.get(i).get(Tab_Chapter.CHAPTER_ID);
            assert idStr != null;
            if (Long.parseLong(idStr) == chapterID) {
                return i;
            }
        }
        return 0;
    }

    private void bindDate() {
        book = (BookInfo) Fun.SHARE_MAP.get(R.string.SHARE_READER);
        assert book != null;

        Tab_BookProgress.BookProgress bookProgress = null;
        if (book.getID() > 0) {
            book.mkdir();
            Tab_Book tab_book = new Tab_Book(this);
            chapters = tab_book.getTab_chapter().get_chapters(book.getID());
            bookProgress = tab_book.getTab_bookProgress().getProgress(book.getID());
            // 测试具体是哪里的异常
//            if (Fun.isDebug() && chapters.size() > 0 && chapters.get(0).size() < 4) {
//                Exception e = new Exception("chapters error");
//                e.printStackTrace();
//            }
            tab_book.close();
        } else {
            book.mkdir(new File(getExternalCacheDir(), Fun.getMD5(book.getFieldValue(R.string.info_uri))));
            chapters = new ArrayList<>();
        }

        Fun.SHARE_MAP.remove(R.string.SHARE_READER);

        if (bookProgress == null) bookProgress = new Tab_BookProgress.BookProgress();
        if (0 == chapters.size()) {
            tv_reader.setVisibility(View.INVISIBLE);
            pb_loading.setVisibility(View.VISIBLE);
            currentChapterIndex = 0;
            Toast.makeText(this, "首次获取章节信息，时间可能较长，请稍等几秒", Toast.LENGTH_LONG).show();
        } else {
            currentChapterIndex = findChapter(bookProgress.chapterID);
            synchronized (this) {
                chapter = new ChapterInfo(book.getBookDir(), chapters.get(currentChapterIndex));

            }
        }
        control.setProgress(bookProgress);
        //更新一下章节数据
        chapters_tmp = new ArrayList<>();
        chaptersThread = new ChapterThread(book, chapters_tmp, handler, true,
                true, this, book.getID());

        chaptersThread.start();
    }

    private ChapterThread chaptersThread;
    List<Map<String, String>> chapters_tmp;
    // private static final int UPDATE_CHAPTER_SQL_FINISH = 200;
    @SuppressWarnings("unchecked")
    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(@NonNull Message msg) {
            switch (msg.what) {
                case HANDLER_CHAPTER_THREAD_MSG:
                    Log.d(TAG, "handleMessage: " + msg);

                    // Tab_Book tab_book = new Tab_Book(context);

                    // chapters = tab_book.getTab_chapter().get_chapters(book.getID());
                    if (chapters.size() != msg.arg1) {
                        synchronized (this) {
                            chapters.clear();
                            chapters.addAll(chapters_tmp);
                            sidebar.adapter.notifyDataSetChanged();
//                            // test
//                            if (Fun.isDebug() && chapters_tmp.size() > 0 && chapters_tmp.get(0).size() < 4) {
//                                Exception e = new Exception("chapters error");
//                                e.printStackTrace();
//                            }
                        }

                    }
                    if (chapter == null) {
                        currentChapterIndex = 0;
                        synchronized (this) {
                            chapter = new ChapterInfo(book.getBookDir(), chapters.get(currentChapterIndex));
                        }

                        Tab_BookProgress.BookProgress bookProgress = control.getProgress();
                        bookProgress.chapterID = chapter.getChapterID();
                        bookProgress.progress = 0;
                        //tab_book.getTab_bookProgress().update(book.getID(), bookProgress.chapterID, 0);

                    }
                    if (chapter.getContent() == null) getContent(ReaderControl.BEGIN);
                    tv_reader.setVisibility(View.VISIBLE);
                    tv_prepare.setVisibility(View.INVISIBLE);
                    pb_loading.setVisibility(View.GONE);
                    if (chaptersThread.isStop() && chapters.size() == msg.arg1) {//添加完了
                        chaptersThread = null;
                        chapters_tmp = null;
                    }
                    break;
                case HANDLER_UPDATE_STATUS:
                    statusBar.updateTime();
                    if (lockScreenTime != -1) {
                        if (--lockScreenCountdown <= 0) {
                            // lockScreenCountdown = lockScreenTime;
                            setScreenOn(false);
                        }
                    }
                    spoken_setting.spokenCountdown();
                    break;
                case HANDLER_GET_CONTENT:
                    if (msg.arg1 == 1) {
                        loading_chapter(CHAPTER_NO_CHANGE, msg.arg2);
                    } else {
                        Toast.makeText(ReaderActivity.this, "获取章节失败，刷新或检查网络", Toast.LENGTH_SHORT).show();
                        controlWindow.setVisibility(true);
                    }
                    break;
                case HANDLER_TALKS_COUNT:
                    if (msg.arg1 == currentChapterIndex) {
                        control.setTalksCount((HashMap<String, String>) msg.obj);
                        postReFill();
                    }
                    break;
                case HANDLER_TALKS_UPDATE:
                    synchronized (talks.adapter) {
                        talks.adapter.notifyDataSetChanged();
                    }
                    break;
            }
            return false;
        }
    });

    /**
     * 获得章节内容，从而分割，填充到control
     */
    void getContent(int startOrEndOrNoChange) {
        if (Fun.isDebug()) Log.d(TAG, "getContent: ");
        if (chapter.getContent() == null) {
            pb_loading.setVisibility(View.VISIBLE);
            ContentThread task = new ContentThread(handler, startOrEndOrNoChange, chapter);
            task.start();
            // task.execute(chapter);
        } else {
            talks.setInfo(book.getFieldValue(R.string.info_name), book.getFieldValue(R.string.info_author),
                    chapter.getName(), currentChapterIndex);
            talks.getTalksCount();
            fillReader(startOrEndOrNoChange);
        }
    }

    //boolean isFirst = true;
    void postReFill() {
        tv_prepare.post(() -> fillReader(ReaderControl.NO_CHANGE));
    }

    void fillReader(int startOrEndOrNoChange) {
        if (Fun.isDebug()) Log.d(TAG, "fillReader: ");
        control.setChapter(chapter);
        control.splitPage();
        //if (isFirst)//第一次打开已经有进度了，不需要更新书籍进度
        //    isFirst = false;
        // else {
        if (startOrEndOrNoChange != ReaderControl.NO_CHANGE) {
            control.resetProgress(startOrEndOrNoChange);
            control.update_SQL(book.getID());
        }
        // }
        control.seekToProgress();
        statusBar.updatePage();
        statusBar.updateChapter();
        if (spoken_setting.isPlaying()) {
            spoken_setting.play(chapter.getName());
            spoken_setting.setTitle();
            spoken_setting.play();
            spoken_setting.playNextPage();
        } else pb_loading.setVisibility(View.INVISIBLE);
    }

    void page_turning(boolean isNext) {
        spoken_setting.setCurPageSpokenProgress();
        if (lockScreenTime != -1) {
            lockScreenCountdown = lockScreenTime;
            setScreenOn(true);
        }
        boolean newChapter;
        int newIndex;
        if (isNext) {
            newIndex = currentChapterIndex + 1;
            newChapter = !control.next() && newIndex < chapters.size();
        } else {
            newIndex = currentChapterIndex - 1;
            newChapter = !control.previous() && newIndex >= 0;
        }
        statusBar.updatePage();
        if (newChapter) {
            loading_chapter(newIndex, isNext ? ReaderControl.BEGIN : ReaderControl.END);
        } else if (spoken_setting.isPlaying()) {
            spoken_setting.playNextPage();
        }
    }

    public void show() {
        Intent intent = new Intent(getApplicationContext(), LaunchActivity.class);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setAction(Intent.ACTION_MAIN);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
        startActivity(intent);
    }


    //给tv_reader用，太长，封装
    private class ReaderOnTouchListener implements View.OnTouchListener {
        class Point {
            int x, y;
        }

        private boolean moved = false;
        private Point downPoint = new Point();
        private boolean isNext;

        @SuppressLint("ClickableViewAccessibility")
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (spoken_setting.isPlaying()) {
                //  spoken_setting.setVisibility(!spoken_setting.isVisibility());
                return false;
            }
            if (talks.isVisibility()) {
                return false;
            }

            RelativeLayout.LayoutParams lp;
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    downPoint.x = (int) event.getX();
                    downPoint.y = (int) event.getY();
                    moved = false;
                    break;
                case MotionEvent.ACTION_MOVE:
                    lp = new RelativeLayout.LayoutParams(tv_prepare.getLayoutParams());
                    int change;
                    if (control.getOrientation() == LinearLayout.HORIZONTAL) {
                        change = (int) (event.getX() - downPoint.x);//变大说明上一页，小下一页
                        final int width = tv_reader.getWidth();
                        if (change > 0) {
                            lp.leftMargin = 0 - width + change;
                            isNext = false;
                        } else if (change < 0) {
                            lp.leftMargin = width + change;
                            isNext = true;
                        }

                        lp.rightMargin = 0 - lp.leftMargin;

                    } else {
                        change = (int) (event.getY() - downPoint.y);//变大说明上一页，小下一页
                        final int height = tv_reader.getHeight();
                        if (change > 0) {
                            lp.topMargin = 0 - height + change;
                            isNext = false;
                        } else if (change < 0) {
                            lp.topMargin = height + change;
                            isNext = true;
                        }
                        lp.bottomMargin = 0 - lp.topMargin;
                    }

                    if (change != 0) {
                        if (tv_prepare.getVisibility() != View.VISIBLE)
                            tv_prepare.setVisibility(View.VISIBLE);
                        control.showPreparePage(change);
                        tv_prepare.setLayoutParams(lp);
                        moved = true;
                    }
                    break;
                case MotionEvent.ACTION_UP:
                    tv_prepare.setVisibility(View.INVISIBLE);

                    if (!moved) {
                        v.setTag(event);

                        //v.performClick();
                    } else {//判断移动方向
                        lp = (RelativeLayout.LayoutParams) tv_prepare.getLayoutParams();
                        TranslateAnimation animation = new TranslateAnimation(0, 0 - lp.leftMargin, 0, 0 - lp.topMargin);

                        animation.setDuration(300);
                        animation.setAnimationListener(new Animation.AnimationListener() {
                            @Override
                            public void onAnimationStart(Animation animation) {
                            }

                            @Override
                            public void onAnimationEnd(Animation animation) {
                                page_turning(isNext);
                            }

                            @Override
                            public void onAnimationRepeat(Animation animation) {

                            }
                        });
                        tv_prepare.startAnimation(animation);
                        return true;
                    }
            }

            return false;
        }
    }
}
